<?php
namespace App\DataBase;


use App\Core\App;

class Factory
{
    private static $_instance;
    private $_PDOClass = 'PDO';
    private $_PDOConnectionList = [];

    private function __construct()
    {
    }

    /**
     * @return Factory
     */
    public static function &getInstance()
    {
        if (!self::$_instance) {
            self::$_instance = new static();
        }
        return self::$_instance;
    }

    /**
     * @param string $configName
     * @return PDO
     */
    public function getPDO($configName)
    {
        if (!isset($this->_PDOConnectionList[$configName])) {
            $this->_PDOConnectionList[$configName] = $this->loadPDO($configName);
        }
        return $this->_PDOConnectionList[$configName];
    }

    /**
     * 获取PDO对象
     *
     * @param string $name
     * @return PDO
     * @throws \App\Exception\SqlException
     */
    public function loadPDO($name)
    {
        $config = App::getInstance()->getConfig($name, 'database');
        /**
         * @var PDO $pdo
         */
        $pdo = new $this->_PDOClass($config['dsn'], @$config['username'], @$config['password'], isset($config['driver_options']) ? $config['driver_options'] : []);

        $pdo->setName($name);

        if (isset($config['default_fetch_mode'])) {
            $pdo->setDefaultFetchMode($config['default_fetch_mode']);
        }

        if (isset($config['init_statements']) && is_array($config['init_statements'])) {
            foreach ($config['init_statements'] as $sql) {
                $pdo->exec($sql);
            }
        }
        return $pdo;
    }

    public function closePDO($name)
    {
        if (isset($this->_PDOConnectionList[$name])) {
            unset($this->_PDOConnectionList[$name]);
        }
    }

    public function closeAll()
    {
        if (!empty($this->_PDOConnectionList)) {
            foreach (array_keys($this->_PDOConnectionList) as $name) {
                unset($this->_PDOConnectionList[$name]);
            }
        }
    }
}